package com.imooc.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.cloud.gateway.filter.ratelimit.RateLimiter;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;

/**
 * 设置路由规则
 *
 * @author 顾志杰
 * @date 2020/9/17-10:09
 */
@Configuration
public class RoutesConfiguration {
    @Autowired
    private KeyResolver keyResolver;

    @Autowired
    @Qualifier("redisRateLimiterUser")
    private RateLimiter rateLimiterUser;

    @Autowired
    @Qualifier("redisRateLimiterItem")
    private RateLimiter rateLimiterItem;


    @Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        // Auth在网关层有很多种做法
        // 1) 【最常用】网关层或微服务自己本地校验jwt token有效性，不向auth-service发起远程调用
        // 2) 【路由配置最简单】可以把AuthFilter注册为global filter，
        //     然后在AuthFilter里配置需要过滤的url pattern(也可以从config-server动态拉取)
        // 3) 【路由配置也简单】也可以采用interceptor的形式
        // 4) 【路由配置最丑】这就是我选的路，只是为了演示下自定义过滤器，才走了这条不归路
        // 要注意声明URL Pattern的先后顺序，一个URL可能匹配多个路由，先来后到
        //
        // FIXME
        // 1) 将其他需要登录校验的地址添加在下面，或者采用上面提到的其他方案改造登录检测过程
        // 2) 修改前端JS代码，记得把login后返回的jwt-token和refresh-token带到每个请求的header里
        // 3) 前端JS依据header中的Authorization来判断是否登录
        return builder.routes()
                /*用户服务*/
                .route(r -> r.path("/address/**", "/center/**", "/userInfo/**", "/passport/**")
                        .filters(f -> f.requestRateLimiter(c -> {
                            c.setKeyResolver(keyResolver);
                            c.setRateLimiter(rateLimiterUser);
                            c.setStatusCode(HttpStatus.BAD_GATEWAY);
                        }))
                        .uri("lb://FOODIE-USER-SERVICE"))
                /*商品服务*/
                .route(r -> r.path("/items/**")
                        .filters(f -> f.requestRateLimiter(c -> {
                            c.setKeyResolver(keyResolver);
                            c.setRateLimiter(rateLimiterItem);
                            c.setStatusCode(HttpStatus.BAD_GATEWAY);
                        }))
                        .uri("lb://FOODIE-ITEM-SERVICE"))
                /*购物车服务*/
                .route(r -> r.path("/shopcart/**")
                        .uri("lb://FOODIE-CART-SERVICE"))
                /*订单服务*/
                .route(r -> r.path("/mycomments/**", "/myorders/**", "/orders/**")
                        .uri("lb://FOODIE-ORDER-SERVICE"))
                /*搜索服务*/
                .route(r -> r.path("/index/**", "/search/**")
                        .uri("lb://FOODIE-SEARCH-SERVICE"))
                .build();
    }
}
